import numpy as np
import pandas as pd
from sklearn.preprocessing import label_binarize
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, auc
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import matplotlib.pyplot as plt
import warnings

plt.rcParams['font.family'] = 'simhei'
plt.rcParams['axes.unicode_minus'] = False
warnings.filterwarnings('ignore')
evaluation = pd.DataFrame({'Model': [],
                           'Accuracy': [],
                           'Micro Precision': [],
                           'Micro Recall': [],
                           'Micro F1-score': [],
                           'Micro AUC': [],
                           '5-fold Cross Validation Score': []})

# 读取数据
df = pd.read_csv("toprankedanime.csv")
df_summary = df.describe(include='object').T
df_summary.plot(kind='bar', title='Summary')
df = df[['score', 'favorites','episodes','type','name']]
df = df.sort_values(by='favorites', ascending=False).head(20)
df = df.sort_values(by='score', ascending=False).head(20)
df = df.sort_values(by='episodes', ascending=False).head(20)
df = df.sort_values(by='type', ascending=False).head(20)
df = df.sort_values(by='name', ascending=False).head(20)

df = df.replace(',', '.',regex=True)
df = df.replace('Unknown', '00',regex=True)
df = df.astype({'score': float})
df = df.astype({'favorites': float})
df = df.astype({'episodes': float})
df.fillna(0, inplace=True)

df.duplicated().sum()

def data_preprocess(X, y, train_size):
    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=train_size, random_state=42)
    return X_train, X_test, y_train, y_test

def plot_D_S(df):
    # 绘制散点图
    df0 = df[df['type'] == 0][['name', 'type']].copy()
    df1 = df[df['type'] == 1][['name', 'type']].copy()
    df2 = df[df['type'] == 2][['name', 'type']].copy()
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.scatter(df0.iloc[:, 0], df0.iloc[:, 1], cmap='Set1', label='TV')
    ax.scatter(df1.iloc[:, 0], df1.iloc[:, 1], cmap='Set2', label='Movie')
    ax.scatter(df2.iloc[:, 0], df2.iloc[:, 1], cmap='Set3', label='TV Special')
    ax.set(xlabel='花茎长度', ylabel='花瓣长度')
    ax.legend(loc='best')
    plt.title('分类散点图')
    plt.savefig('S_I.jpg')

def s_W_D_K(svm_model, kernel, penalty_parameter, X_train, X_test, y_train, y_test):
    # 使用SVM模型进行训练和预测
    model = svm_model
    model.fit(X_train, y_train)
    y_test_predict = model.predict(X_test)
    print("预测结果：", y_test_predict)
    # 计算评估指标
    acc_test = accuracy_score(y_test, y_test_predict)
    precision_test = precision_score(y_test, y_test_predict, average='micro')
    recall_test = recall_score(y_test, y_test_predict, average="micro")
    f1_test = f1_score(y_test, y_test_predict, average="micro")
    y_test_predict_proba = model.decision_function(X_test)  # 修改为 decision_function
    n_class = 3
    y_test_one_hot = label_binarize(y_test, classes=np.unique(y_train))  # 修改为 np.unique(y_train)
    false_positive_rate, recall, thresholds = roc_curve(y_test_one_hot.ravel(), y_test_predict_proba.ravel())
    roc_auc = auc(false_positive_rate, recall)
    plt.figure()
    plt.title('SVM分类模型(核函数{},惩罚项函数为{})的ROC_AUC图'.format(kernel, penalty_parameter))
    plt.plot(false_positive_rate, recall, 'r', label="AUC = %0.3f" % roc_auc)
    plt.legend(loc='best')
    plt.plot([0, 1], [0, 1], 'k--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.0])
    plt.ylabel('真正概率（召回率）')
    plt.xlabel('假正概率')
    plt.savefig('R_A_S_W__C_{}.jpg'.format(kernel, penalty_parameter))
    # 计算交叉验证分数
    cv_test = float(format(cross_val_score(model, X_test, y_test, cv=5).mean(), '.3f'))
    r = evaluation.shape[0]
    evaluation.loc[r] = ['SVM分类模型(核函数{},惩罚项函数为{})'.format(kernel, penalty_parameter), acc_test,
                         precision_test, recall_test, f1_test, roc_auc, cv_test]

if __name__ == '__#main__':
    train_size = 0.67
    X = df[['score', 'favorites']].values
    y = df['episodes'].values
    X_train, X_test, y_train, y_test = data_preprocess(X, y, train_size)
    plot_D_S(df)
    kernels = ['linear', 'poly', 'rbf', 'sigmoid']
    penalty_parameter = [0.5,1,1.5,2,2.5]
    for C in penalty_parameter:
        for kernel in kernels:
            model = SVC(kernel=kernel, C=C, probability=True)  # 添加 probability=True
            s_W_D_K(model, kernel, C, X_train, X_test, y_train, y_test)